package io.renren.modules.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.common.utils.MyRandomCode;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.common.utils.R;
import io.renren.common.validator.Assert;
import io.renren.common.validator.ValidatorUtils;
import io.renren.modules.app.dao.UserDao;
import io.renren.modules.app.entity.MemberGradeEntity;
import io.renren.modules.app.entity.MemberPurseEntity;
import io.renren.modules.app.entity.UserEntity;
import io.renren.modules.app.entity.vo.QueryMyTeamParam;
import io.renren.modules.app.entity.vo.SelectMyTeanData;
import io.renren.modules.app.entity.vo.SelectWithdrawalsData;
import io.renren.modules.app.form.LoginForm;
import io.renren.modules.app.form.RegisterForm;
import io.renren.modules.app.service.MemberGradeService;
import io.renren.modules.app.service.MemberPurseService;
import io.renren.modules.app.service.TradeRecordingService;
import io.renren.modules.app.service.UserService;
import io.renren.modules.app.utils.StringUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    @Autowired
    public MemberPurseService memberPurseService;

    @Autowired
    private MemberGradeService memberGradeService;

    @Autowired
    private TradeRecordingService tradeRecordingService;


    /**
     * 用户注册
     *
     * @param form 注册参数类
     * @return
     */
    @Transactional
    @Override
    public Integer register(RegisterForm form) {
        //表单校验
        ValidatorUtils.validateEntity(form);
        //获取会员等级最小值
        MemberGradeEntity memberGrade = memberGradeService.queryMemberGradeByMin();
        UserEntity user = new UserEntity();
        user.setMobile(form.getMobile());
        user.setPassword(DigestUtils.sha256Hex(form.getPassword()));
        user.setTradePass(DigestUtils.sha256Hex(form.getTradePass()));
        //随机获取8位数字邀请码
        user.setInvitationCode(MyRandomCode.generateNumbers());
        //随机获取昵称
        user.setUsername(MyRandomCode.getNickname());
        user.setCreateTime(new Date());
        if (StringUtils.isNotNull(memberGrade)) {
            user.setGradeId(memberGrade.getGradeId());
            user.setTakeOrdersFrequency(memberGrade.getTakeOrdersFrequency());
        }
        int insert = baseMapper.insert(user);
        if (insert > 0) {
            MemberPurseEntity memberPurse = new MemberPurseEntity();
            memberPurse.setUserId(user.getUserId());
            memberPurse.setWithdrawalsAmount(BigDecimal.valueOf(0.00));
            memberPurse.setFreezeAmount(BigDecimal.valueOf(0.00));
            memberPurse.setCreateTime(new Date());
            memberPurseService.addMemberPurse(memberPurse);
        }
        return insert;
    }

    /**
     * 修改密码
     *
     * @param user 用户信息类
     * @return
     */
    @Transactional
    @Override
    public Integer editPassword(UserEntity user) {
        UpdateWrapper<UserEntity> wrapper = new UpdateWrapper<>();
        if (user.getUserId() != null) {
            wrapper.eq("user_id", user.getUserId());
        }
        return baseMapper.update(user, wrapper);
    }


    /**
     * 获取会员列表
     *
     * @param params 参数类
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String mobile = params.get("mobile").toString();
        String nickname = params.get("nickname").toString();
        String status = params.get("status").toString();
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(mobile)) {
            wrapper.eq("mobile", mobile);
        }
        if (StringUtils.isNotEmpty(nickname)) {
            wrapper.eq("nickname", nickname);
        }
        if (StringUtils.isNotEmpty(status)) {
            wrapper.eq("status", status);
        }
        IPage<UserEntity> page = this.page(new Query<UserEntity>().getPage(params), wrapper);
        return new PageUtils(page);
    }

    /**
     * 根据手机号码获取用户信息
     *
     * @param mobile 手机号码
     * @return
     */
    @Override
    public UserEntity queryByMobile(String mobile) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("mobile", mobile));
    }

    /**
     * 用户登录
     *
     * @param form 登录表单
     * @return 返回用户ID
     */
    @Override
    public long login(LoginForm form) {
        UserEntity user = queryByMobile(form.getMobile());
        Assert.isNull(user, "手机号错误");

        //密码错误
        if (!user.getPassword().equals(DigestUtils.sha256Hex(form.getPassword()))) {
            throw new RRException("密码错误");
        }

        return user.getUserId();
    }

    /**
     * 获取用户详情
     *
     * @param user 用户信息类
     * @return
     */
    @Override
    public UserEntity queryUserDetails(UserEntity user) {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        if (user.getUserId() != null) {
            wrapper.eq("user_id", user.getUserId());
        }
        if (StringUtils.isNotEmpty(user.getMobile())) {
            wrapper.eq("mobile", user.getMobile());
        }
        if (StringUtils.isNotEmpty(user.getNickname())) {
            wrapper.eq("nickname", user.getNickname());
        }
        if (user.getPassword() != "" && user.getPassword() != null) {
            wrapper.eq("password", user.getPassword());
        }
        if (user.getTradePass() != "" && user.getTradePass() != null) {
            wrapper.eq("trade_pass", user.getTradePass());
        }
        return baseMapper.selectOne(wrapper);
    }

    /**
     * 编辑用户信息
     *
     * @param user 用户信息
     * @return
     */
    @Override
    public Integer editUser(UserEntity user) {
        UpdateWrapper<UserEntity> wrapper = new UpdateWrapper<>();
        if (user.getUserId() != null) {
            wrapper.eq("user_id", user.getUserId());
        }
        return baseMapper.update(user, wrapper);
    }


    @Override
    public List<UserEntity> queryUserList(UserEntity user) {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        if (user.getUserId() != null) {
            wrapper.eq("user_id", user.getUserId());
        }
        if (user.getInvitationCode() != null) {
            wrapper.eq("invitation_code", user.getInvitationCode());
        }
        if (user.getInviteCode() != null) {
            wrapper.eq("invite_code", user.getInviteCode());
        }
        return baseMapper.selectList(wrapper);
    }

    /**
     * 根据被邀请码查询用户
     *
     * @param inviteCodes 被邀请码 list
     * @return
     */
    @Override
    public List<UserEntity> queryUserListByInviteCodes(List<String> inviteCodes) {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(inviteCodes)) {
            wrapper.in("invite_code", inviteCodes);
        }
        return baseMapper.selectList(wrapper);
    }

    /**
     * 条件查询我的团队
     *
     * @param user
     * @return
     */
    @Override
    public SelectMyTeanData queryMyTeam(QueryMyTeamParam user) {
        SelectMyTeanData data = new SelectMyTeanData();
        //直属下属(一级)
        if (user.getCount().equals(0)) {
            UserEntity userEntity = new UserEntity();
            userEntity.setUserId(user.getUserId());
            //当前用户
            UserEntity userEntities = queryUserDetails(userEntity);
            //当前用户邀请码
            String invitationCode = userEntities.getInvitationCode();
            QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("invite_code", invitationCode);
            wrapper.orderByDesc("create_time");
            Page<UserEntity> iPage = new Page<>(user.getPageNum(), user.getPageSize());
            IPage<UserEntity> cookBookIPage = baseMapper.selectPage(iPage, wrapper);
            List<UserEntity> userList = cookBookIPage.getRecords();
            for (UserEntity user1 : userList) {
                //统计充值金额
                BigDecimal rechargeTimes = tradeRecordingService.statisticsUserTrade(user1.getUserId(), 0);
                user1.setRechargeAmount(rechargeTimes);
                //统计提现金额
                BigDecimal withdrawalTimes = tradeRecordingService.statisticsUserTrade(user1.getUserId(), 1);
                user1.setWithdrawAmount(withdrawalTimes);
                //统计下级人数
                Integer lowerLevelNum = statisticsLowerLevelNum(user1.getInvitationCode());
                user1.setLowerLevelNum(lowerLevelNum);
            }
            data.setTotal(cookBookIPage.getTotal());
            data.setCurrentIndex(cookBookIPage.getCurrent());
            data.setSize(cookBookIPage.getSize());
            data.setPageCount(cookBookIPage.getPages());
            data.setUserList(userList);
            return data;

            //二级下属
        } else if (user.getCount().equals(1)) {
            UserEntity userEntity = new UserEntity();
            userEntity.setUserId(user.getUserId());
            //当前用户
            UserEntity userEntities = queryUserDetails(userEntity);
            //当前用户邀请码
            String invitationCode = userEntities.getInvitationCode();

            UserEntity userEn = new UserEntity();
            userEn.setInviteCode(invitationCode);
            //一级下属
            List<UserEntity> userEnList = queryUserList(userEn);

            //一级下属邀请码集合
            List<String> invitationCode1 = new ArrayList<>();
            QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
            for (UserEntity users : userEnList) {
                if (StringUtils.isNotEmpty(users.getInvitationCode())) {
                    invitationCode1.add(users.getInvitationCode());
                }
            }
            wrapper.in("invite_code", invitationCode1);
            wrapper.orderByDesc("create_time");
            Page<UserEntity> iPage = new Page<>(user.getPageNum(), user.getPageSize());
            IPage<UserEntity> cookBookIPage = baseMapper.selectPage(iPage, wrapper);
            List<UserEntity> userList = cookBookIPage.getRecords();
            for (UserEntity user1 : userList) {
                //统计充值金额
                BigDecimal rechargeTimes = tradeRecordingService.statisticsUserTrade(user1.getUserId(), 0);
                user1.setRechargeAmount(rechargeTimes);
                //统计提现金额
                BigDecimal withdrawalTimes = tradeRecordingService.statisticsUserTrade(user1.getUserId(), 1);
                user1.setWithdrawAmount(withdrawalTimes);
                //统计下级人数
                Integer lowerLevelNum = statisticsLowerLevelNum(user1.getInvitationCode());
                user1.setLowerLevelNum(lowerLevelNum);
            }

            data.setTotal(cookBookIPage.getTotal());
            data.setCurrentIndex(cookBookIPage.getCurrent());
            data.setSize(cookBookIPage.getSize());
            data.setPageCount(cookBookIPage.getPages());
            data.setUserList(userList);
            return data;

            //三级下属
        } else if (user.getCount().equals(2)) {
            UserEntity userEntity = new UserEntity();
            userEntity.setUserId(user.getUserId());
            //当前用户
            UserEntity userEntities = queryUserDetails(userEntity);
            //当前用户邀请码
            String invitationCode = userEntities.getInvitationCode();

            UserEntity userEn = new UserEntity();
            userEn.setInviteCode(invitationCode);
            //一级下属
            List<UserEntity> oneSubordinate = queryUserList(userEn);
            //一级下属邀请码集合
            List<String> invitationCode1 = new ArrayList<>();
            for (UserEntity use : oneSubordinate) {
                if (StringUtils.isNotEmpty(use.getInvitationCode())) {
                    invitationCode1.add(use.getInvitationCode());
                }
            }

            //二级下属数据
            List<UserEntity> twoSubordinate = queryUserListByInviteCodes(invitationCode1);
            //二级下属邀请码集合
            List<String> invitationCode2 = new ArrayList<>();
            for (UserEntity use2 : twoSubordinate) {
                if (StringUtils.isNotEmpty(use2.getInvitationCode())) {
                    invitationCode2.add(use2.getInvitationCode());
                }
            }
            QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
            wrapper.in("invite_code", invitationCode2);
            wrapper.orderByDesc("create_time");
            Page<UserEntity> iPage = new Page<>(user.getPageNum(), user.getPageSize());
            IPage<UserEntity> cookBookIPage = baseMapper.selectPage(iPage, wrapper);
            List<UserEntity> userList = cookBookIPage.getRecords();
            for (UserEntity user1 : userList) {
                //统计充值金额
                BigDecimal rechargeTimes = tradeRecordingService.statisticsUserTrade(user1.getUserId(), 0);
                user1.setRechargeAmount(rechargeTimes);
                //统计提现金额
                BigDecimal withdrawalTimes = tradeRecordingService.statisticsUserTrade(user1.getUserId(), 1);
                user1.setWithdrawAmount(withdrawalTimes);
                //统计下级人数
                Integer lowerLevelNum = statisticsLowerLevelNum(user1.getInvitationCode());
                user1.setLowerLevelNum(lowerLevelNum);
            }


            data.setTotal(cookBookIPage.getTotal());
            data.setCurrentIndex(cookBookIPage.getCurrent());
            data.setSize(cookBookIPage.getSize());
            data.setPageCount(cookBookIPage.getPages());
            data.setUserList(userList);
            return data;
        }

        return data;
    }

    /**
     * 统计下级人数
     *
     * @param inviteCode 被邀请码
     * @return
     */
    @Override
    public Integer statisticsLowerLevelNum(String inviteCode) {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(inviteCode)) {
            wrapper.eq("invite_code", inviteCode);
        }
        return baseMapper.selectCount(wrapper);
    }
}
